﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using MSWord = Microsoft.Office.Interop.Word;

namespace UpdateWordDocx
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * 这个是演示用的示例数据，key表示word中的占位符，value表示要替换的内容
             */
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("{test1}", "test1");
            dic.Add("{test2}", "test2");

            /*
             * 这个是你的Word模板
             * 写两个占位符：{test1}、{test1}
             * 添加一个书签：你的富文本书签名字
             */
            var templateWord = "D:\\template.docx";
            object exportWord = string.Format("D:\\{0}.docx", Guid.NewGuid().ToString());

            //复制模板文件（这样后续的操作就不会影响到模板文件，如果是要直接操作模板文件的话，忽略这一步）
            File.Copy(templateWord, exportWord.ToString(), true);

            MSWord.Application app = null;
            MSWord.Document doc = null;
            try
            {
                //创建word应用程序
                app = new MSWord.Application();

                //定义缺省值
                object oMissing = System.Reflection.Missing.Value;

                //打开Word文件，如果不存在的话，新建
                if (exportWord == null)
                {
                    doc = app.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
                }
                else
                {
                    doc = app.Documents.Open(ref exportWord,
                    ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                    ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                    ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
                }

                //*********上面这一段多是固定写法，直接抄就是了******************

                #region 替换占位符，这里演示替换多个占位符

                object replace = MSWord.WdReplace.wdReplaceAll;
                if (dic != null)
                {
                    foreach (var item in dic)
                    {
                        app.Selection.Find.Replacement.ClearFormatting();
                        app.Selection.Find.ClearFormatting();
                        app.Selection.Find.Text = item.Key;//需要被替换的文本
                        app.Selection.Find.Replacement.Text = item.Value;//替换文本 

                        //执行替换操作，这样就完事儿了
                        app.Selection.Find.Execute(ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref replace,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing);
                    }
                }

                #endregion

                #region 插入富文本类型的值，保留html样式

                /*
                 * 插入富文本类型的值，并保留html样式
                 * 这里用到了Word里的书签，其实就是在指定书签位置插入富文本值
                 * 我查了资料，最后只能这样实现，不知道有没有更好的办法
                 * 1、将富文本内容写入到本地临时html文件，这里一定要注意，！！！！html文件的标记必须完整，方法在示例里有！！！！！
                 * 2、使用InsertFile方法插入到指定书签
                 * 3、删除临时文件
                 */

                //1、将要插入的富文本内容写入到本地的临时文件
                string tempPath = string.Format("D:\\{0}.html", Guid.NewGuid().ToString());
                StreamWriter streamWriter = null;
                FileStream fileStream = null;
                try
                {
                    fileStream = new FileStream(tempPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    streamWriter = new StreamWriter(fileStream, Encoding.GetEncoding("UTF-8")); // 创建写入流，！！！记得编码格式！！！
                    streamWriter.Write("<html><head></head><body>");//！！！这里就是向富文本文件里添加HTML完整标记，如果你的富文本里本来就有这两个标记，可以忽略这一步！！！
                    streamWriter.WriteLine("<p>这个是你的富文本内容</p>"); // 写入Hello World
                    streamWriter.Write("</body></html>");
                }
                catch (Exception) { }
                finally
                {
                    streamWriter.Close();
                    streamWriter.Dispose();
                }

                //2、使用InsertFile方法插入到指定书签
                MSWord.Range rangHtml = app.Selection.Range;
                if (doc.Bookmarks.Count != 0 && doc.Bookmarks.get_Item("你的富文本书签名字").Range != null)
                    rangHtml = doc.Bookmarks.get_Item("你的富文本书签名字").Range;
                rangHtml.InsertFile(tempPath);

                //3、删除临时文件
                File.Delete(tempPath);

                #endregion

                #region 插入表格，后续补充

                #endregion

                #region 保存，上面的任意一个操作或多个操作执行完之后，都可以直接进行保存

                doc.SaveAs(exportWord,
                   oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing,
                   oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);

                #endregion
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (doc != null)
                {
                    doc.Close();//关闭word文档
                }
                if (app != null)
                {
                    app.Quit();//退出word应用程序
                }
            }
        }
    }
}